///////////////////////////////////////////////////////////
///////////////// Have an itch? Scratch it! ///////////////
///////////////////////// SCRATCH /////////////////////////
/////////////////////  A MUD  Server   ////////////////////
///////////////////// By: Jared Devall ////////////////////
/////////////////////      Thanks:     ////////////////////
/////////////////////  DIKU/Merc/ROM   ////////////////////
///////////////////// Aetas/Deus Gang  ////////////////////
/////////////////////       Beej       ////////////////////
///////////////////////////////////////////////////////////

#ifndef __COMMANDTABLE_CPP_
#define __COMMANDTABLE_CPP_

#include "definitions.h"
#include <list>
#include "commandTable.h"
#include "world.h"
#include "stringutil.h"
#include "split.h"

using namespace std;

/////////////////////////////////////// regular command table //////////////////////////////////////

CommandTable::CommandTable() {	
	LoadCommands();	
}	

bool CommandTable::LoadCommands() {
	// Populate list with commands
	// Keep in alphabetical order, except directional commands,
	// They should go first within that letter. That way, users
	// can type "n" for north, "e" for east, etc.
	_commands.push_back( new CmdAedit );
	_commands.push_back( new CmdAlist );
	_commands.push_back( new CmdAsave );
	_commands.push_back( new CmdBoards );
	_commands.push_back( new CmdBuzz );
	_commands.push_back( new CmdClose );
	_commands.push_back( new CmdColors );
	_commands.push_back( new CmdCommands );
	_commands.push_back( new CmdDown );
	_commands.push_back( new CmdDemote );
	_commands.push_back( new CmdDescription );
	_commands.push_back( new CmdDisable );
	_commands.push_back( new CmdDisconnect );
	_commands.push_back( new CmdDrop );
	_commands.push_back( new CmdEast );
	_commands.push_back( new CmdEat );
	_commands.push_back( new CmdEmote );
	_commands.push_back( new CmdEnable );
	_commands.push_back( new CmdGecho );
	_commands.push_back( new CmdGet );
	_commands.push_back( new CmdGive );
	_commands.push_back( new CmdGoto );
	_commands.push_back( new CmdHelp );
	_commands.push_back( new CmdInformation );
	_commands.push_back( new CmdInventory );
	_commands.push_back( new CmdLook );
	_commands.push_back( new CmdMedit );
	_commands.push_back( new CmdMlist );
	_commands.push_back( new CmdMload );
	_commands.push_back( new CmdNorth );
	_commands.push_back( new CmdNotes );
	_commands.push_back( new CmdOedit );
	_commands.push_back( new CmdOlist );
	_commands.push_back( new CmdOload );
	_commands.push_back( new CmdOmninet );
	_commands.push_back( new CmdOmniset );
	_commands.push_back( new CmdOpen );
	_commands.push_back( new CmdPassword );
	_commands.push_back( new CmdPedit );
	_commands.push_back( new CmdPoofin );
	_commands.push_back( new CmdPoofout );
	_commands.push_back( new CmdPoofs );
	_commands.push_back( new CmdPromote );
	_commands.push_back( new CmdPrompt );
	_commands.push_back( new CmdPut );
	_commands.push_back( new CmdQuit );
	_commands.push_back( new CmdReboot );
	_commands.push_back( new CmdRedit );
	_commands.push_back( new CmdReply );
	_commands.push_back( new CmdSouth );
	_commands.push_back( new CmdSave );
	_commands.push_back( new CmdSay );
	_commands.push_back( new CmdScore );
	_commands.push_back( new CmdShutdown );
	_commands.push_back( new CmdSiteban );
	_commands.push_back( new CmdSockets );
	_commands.push_back( new CmdTake );
	_commands.push_back( new CmdTell );
	_commands.push_back( new CmdTimers );
	_commands.push_back( new CmdTitle );
	_commands.push_back( new CmdUp );
	_commands.push_back( new CmdWest );
	_commands.push_back( new CmdWho );
	_commands.push_back( new CmdWhos );
	return true;
}

Command* CommandTable::FindCommand( Character* c, const string& command, bool shortcut ) {
	list< Command* >::iterator it;
	string command1;
	rtrim( command1, command );

	for ( it = _commands.begin(); it != _commands.end(); ++it ) {
		
		// If it's a shortcut, check against the commands shortcut
		if ( shortcut == true && !(*it)->_shortcut.empty() ) {
			if ( ( str_cmp( (*it)->_shortcut, command1 ) ) ) {
				// Check level-based permissions.
				if ( (*it)->_level > c->getLevel() ) {
					c->Send( "Huh?\n\r" );
					return 0;
				} else if ( (*it)->_enabled == false ) {
					c->Send( "That command is disabled.\n\r" );
					return 0;
				} else if ( (*it)->_enabled == false ) {
					c->Send( "Huh?\n\r" );
					return 0;
				} else
					return (*it);
			}
		}	
		if ( str_cmp( (*it)->_name, command1 ) || str_prefix( command1, (*it)->_name ) ) {
			// Check level-based permissions.
			if ( (*it)->_level > c->getLevel() ) {
				c->Send( "Huh?\n\r" );
				return 0;
			} else if ( (*it)->_enabled == false ) {
				c->Send( "That command is disabled.\n\r" );
				return 0;
			} else if ( (*it)->_enabled == false ) {
				c->Send( "Huh?\n\r" );
				return 0;
			} else
				return (*it);
		}
	}
	c->Send( "Huh?\n\r" );
	return NULL;
}

bool CommandTable::Execute( Character* c, const string& commandAndArgs ) {
	string commandss = commandAndArgs;
	string command1;
	string arguments;
	Command * command = 0;
	string buf;
	bool shortcut = false;
	list< Command* >::iterator it;

	if ( commandAndArgs.empty() || commandAndArgs[0] == '\n' || commandAndArgs[0] == '\r' )
		return false;

	// Check to see if there is a 'shortcut' used. Really checking if
	// it's a nonalphanumeric character.	
	for ( string::iterator cChar = commandss.begin(); cChar != commandss.end(); ++cChar ) {
		if ( !isalpha( (*cChar) ) && !isdigit( (*cChar) ) && cChar == commandss.begin() ) {
			command1 = (*cChar);
			shortcut = true;
		} else {
			arguments << (*cChar);
		}
	 }
	 // No shortcut
	 if ( shortcut == false ) {
		 arguments.erase();
		 split( commandAndArgs, command1, arguments );
		 rtrim( command1, command1 );

		 rtrim( arguments, arguments );
	 }

	if ( ( command = FindCommand( c, command1, shortcut ) ) != 0 ) {
		if ( command->_omniset ) {
			std::string omni;
			omni << c->getName() << ": " << command->_name;
			if ( !arguments.empty() )
				omni << " \"" << arguments << "\"";
			World::Instance().Omninet( omni, STANDARD, c );
		}
		command->Execute( c, arguments );
		return true;
	}

	return false;
}

/////////////////////////////////////// nedit command table //////////////////////////////////////

nCommandTable::nCommandTable() {	
	LoadCommands();	
}

bool nCommandTable::LoadCommands() {
	// Populate list with commands
	// (Keep in alphabetical order... it's MUCH easier
	_commands.push_back( new  CmdBoards );
	_commands.push_back( new nCmdBody );
	_commands.push_back( new nCmdCommands );
	_commands.push_back( new nCmdDelete );
	_commands.push_back( new nCmdExit );
	_commands.push_back( new  CmdHelp );
	_commands.push_back( new nCmdList );
	_commands.push_back( new nCmdNew );
	_commands.push_back( new nCmdRecipient );
	_commands.push_back( new nCmdSelect );
	_commands.push_back( new nCmdSend );
	_commands.push_back( new nCmdSubject );
	_commands.push_back( new nCmdView );
	return true;
}

Command* nCommandTable::FindCommand( Character* c, const string& command, bool shortcut ) {
	list< Command* >::iterator it;
	string command1;
	rtrim( command1, command );

	for ( it = _commands.begin(); it != _commands.end(); ++it ) {
		
		// If it's a shortcut, check against the commands shortcut
		if ( shortcut == true && !(*it)->_shortcut.empty() ) {
			if ( ( str_cmp( (*it)->_shortcut, command1 ) ) ) {
				if ( (*it)->_enabled == false ) {
					c->Send( "That command is disabled.\n\r" );
					return NULL;
				} else if ( (*it)->_enabled == false ) {
					c->Send( "That is an invalid command.\n\r" );
					return NULL;
				}
				return (*it);
			}
		}	
		if ( str_cmp( (*it)->_name, command1 ) || str_prefix( command1, (*it)->_name ) ) {
		   return (*it);
		}
	}
	return NULL;
}

bool nCommandTable::Execute( Character* c, const string& commandAndArgs ) {
	string commandss = commandAndArgs;
	string command1;
	string arguments;
	Command* command = 0;
	string buf;
	bool shortcut = false;
	list< Command* >::iterator it;

	if ( commandAndArgs.empty() || commandAndArgs[0] == '\n' || commandAndArgs[0] == '\r' )
		return false;

	// Check to see if there is a 'shortcut' used. Really checking if
	// it's a nonalphanumeric character.	
	for ( string::iterator cChar = commandss.begin(); cChar != commandss.end(); ++cChar ) {
		if ( !isalpha( (*cChar) ) && !isdigit( (*cChar) ) && cChar == commandss.begin() ) {
			command1 = (*cChar);
			shortcut = true;
		} else {
			arguments << (*cChar);
		}
	 }
	 // No shortcut
	 if ( shortcut == false ) {
		 arguments.erase();
		 split( commandAndArgs, command1, arguments );
		 rtrim( command1, command1 );
		 rtrim( arguments, arguments );
	 }

	if ( ( command = FindCommand( c, command1, shortcut ) ) != 0 ) {
		if ( command->_omniset ) {
			std::string omni;
			omni << c->getName() << " [aedit]: " << command->_name;
			if ( !arguments.empty() )
				omni << " \"" << arguments << "\"";
			World::Instance().Omninet( omni, STANDARD, c, true );
		}
		command->Execute( c, arguments );
		return true;
	}

	c->Send( "That is an invalid command.\n\r" );
	return false;
}

/////////////////////////////////////// aedit command table //////////////////////////////////////

aCommandTable::aCommandTable() {	
	LoadCommands();	
}

bool aCommandTable::LoadCommands() {
	// Populate list with commands
	// (Keep in alphabetical order... it's MUCH easier
	_commands.push_back( new  CmdAlist );
	_commands.push_back( new aCmdCommands );
	_commands.push_back( new aCmdExit );
	_commands.push_back( new  CmdGecho );
	_commands.push_back( new  CmdHelp );
	_commands.push_back( new aCmdKeyword );
	_commands.push_back( new aCmdList );
	_commands.push_back( new aCmdMake );
	_commands.push_back( new aCmdName );
	_commands.push_back( new aCmdPermissions );
	_commands.push_back( new aCmdRemove );
	_commands.push_back( new  CmdReply );
	_commands.push_back( new  CmdSay );
	_commands.push_back( new aCmdSelect );
	_commands.push_back( new  CmdTell );
	_commands.push_back( new aCmdView );
	return true;
}

Command* aCommandTable::FindCommand( Character* c, const string& command, bool shortcut ) {
	list< Command* >::iterator it;
	string command1;
	rtrim( command1, command );

	for ( it = _commands.begin(); it != _commands.end(); ++it ) {
		
		// If it's a shortcut, check against the commands shortcut
		if ( shortcut == true && !(*it)->_shortcut.empty() ) {
			if ( ( str_cmp( (*it)->_shortcut, command1 ) ) ) {
				if ( (*it)->_enabled == false ) {
					c->Send( "That command is disabled.\n\r" );
					return NULL;
				} else if ( (*it)->_enabled == false ) {
					c->Send( "That is an invalid command.\n\r" );
					return NULL;
				}
				return (*it);
			}
		}	
		if ( str_cmp( (*it)->_name, command1 ) || str_prefix( command1, (*it)->_name ) ) {
		   return (*it);
		}
	}
	return NULL;
}

bool aCommandTable::Execute( Character* c, const string& commandAndArgs ) {
	string commandss = commandAndArgs;
	string command1;
	string arguments;
	Command* command = 0;
	string buf;
	bool shortcut = false;
	list< Command* >::iterator it;

	if ( commandAndArgs.empty() || commandAndArgs[0] == '\n' || commandAndArgs[0] == '\r' )
		return false;

	// Check to see if there is a 'shortcut' used. Really checking if
	// it's a nonalphanumeric character.	
	for ( string::iterator cChar = commandss.begin(); cChar != commandss.end(); ++cChar ) {
		if ( !isalpha( (*cChar) ) && !isdigit( (*cChar) ) && cChar == commandss.begin() ) {
			command1 = (*cChar);
			shortcut = true;
		} else {
			arguments << (*cChar);
		}
	 }
	 // No shortcut
	 if ( shortcut == false ) {
		 arguments.erase();
		 split( commandAndArgs, command1, arguments );
		 rtrim( command1, command1 );
		 rtrim( arguments, arguments );
	 }

	if ( ( command = FindCommand( c, command1, shortcut ) ) != 0 ) {
		if ( command->_omniset ) {
			std::string omni;
			omni << c->getName() << " [aedit]: " << command->_name;
			if ( !arguments.empty() )
				omni << " \"" << arguments << "\"";
			World::Instance().Omninet( omni, STANDARD, c, true );
		}
		command->Execute( c, arguments );
		return true;
	}

	c->Send( "That is an invalid command.\n\r" );
	return false;
}

/////////////////////////////////////// medit command table //////////////////////////////////////

mCommandTable::mCommandTable() {
	LoadCommands();	
}

bool mCommandTable::LoadCommands() {
	// Populate list with commands
	// (Keep in alphabetical order... it's MUCH easier)
	_commands.push_back( new mCmdAc );
	_commands.push_back( new mCmdAcbash );
	_commands.push_back( new mCmdAcslash );
	_commands.push_back( new mCmdAcpierce );
	_commands.push_back( new mCmdAcexotic );
	_commands.push_back( new mCmdCha );
	_commands.push_back( new mCmdClass );
	_commands.push_back( new mCmdCommands );
	_commands.push_back( new mCmdCon );
	_commands.push_back( new mCmdDr );
	_commands.push_back( new mCmdDescription );
	_commands.push_back( new mCmdDex );
	_commands.push_back( new mCmdExit );
	_commands.push_back( new  CmdGecho );
	_commands.push_back( new mCmdGender );
	_commands.push_back( new  CmdHelp );
	_commands.push_back( new mCmdHp );
	_commands.push_back( new mCmdHr );
	_commands.push_back( new mCmdInt );
	_commands.push_back( new mCmdLevel );
	_commands.push_back( new mCmdLong );
	_commands.push_back( new mCmdMana );
	_commands.push_back( new mCmdMove );
	_commands.push_back( new mCmdName );
	_commands.push_back( new mCmdRace );
	_commands.push_back( new  CmdReply );
	_commands.push_back( new mCmdSaves );
	_commands.push_back( new  CmdSay );
	_commands.push_back( new mCmdShort );
	_commands.push_back( new mCmdStr );
	_commands.push_back( new  CmdTell );
	_commands.push_back( new mCmdView );
	_commands.push_back( new mCmdWimpy );
	_commands.push_back( new mCmdWis );
	return true;
}

Command* mCommandTable::FindCommand( Character* c, const string& command, bool shortcut ) {
	list< Command* >::iterator it;
	string command1;
	rtrim( command1, command );

	for ( it = _commands.begin(); it != _commands.end(); ++it ) {
		
		// If it's a shortcut, check against the commands shortcut
		if ( shortcut == true && !(*it)->_shortcut.empty() ) {
			if ( ( str_cmp( (*it)->_shortcut, command1 ) ) ) {
				if ( (*it)->_enabled == false ) {
					c->Send( "That command is disabled.\n\r" );
					return NULL;
				} else if ( (*it)->_enabled == false ) {
					c->Send( "That is an invalid command.\n\r" );
					return NULL;
				}
				return (*it);
			}
		}	
		if ( str_cmp( (*it)->_name, command1 ) || str_prefix( command1, (*it)->_name ) ) {
		   return (*it);
		}
	}
	return NULL;
}

bool mCommandTable::Execute( Character* c, const string& commandAndArgs ) {
	string commandss = commandAndArgs;
	string command1;
	string arguments;
	Command* command = 0;
	string buf;
	bool shortcut = false;
	list< Command* >::iterator it;

	if ( commandAndArgs.empty() || commandAndArgs[0] == '\n' || commandAndArgs[0] == '\r' )
		return false;

	// Check to see if there is a 'shortcut' used. Really checking if
	// it's a nonalphanumeric character.	
	for ( string::iterator cChar = commandss.begin(); cChar != commandss.end(); ++cChar ) {
		if ( !isalpha( (*cChar) ) && !isdigit( (*cChar) ) && cChar == commandss.begin() ) {
			command1 = (*cChar);
			shortcut = true;
		} else {
			arguments << (*cChar);
		}
	 }
	 // No shortcut
	 if ( shortcut == false ) {
		 arguments.erase();
		 split( commandAndArgs, command1, arguments );
		 rtrim( command1, command1 );
		 rtrim( arguments, arguments );
	 }

	if ( ( command = FindCommand( c, command1, shortcut ) ) != 0 ) {
		if ( command->_omniset ) {
			std::string omni;
			omni << c->getName() << " [medit]: " << command->_name;
			if ( !arguments.empty() )
				omni << " \"" << arguments << "\"";
			World::Instance().Omninet( omni, STANDARD, c, true );
		}
		command->Execute( c, arguments );
		return true;
	}

	c->Send( "That is an invalid command.\n\r" );
	return false;
}

/////////////////////////////////////// oedit command table //////////////////////////////////////

oCommandTable::oCommandTable() {	
	LoadCommands();	
}

bool oCommandTable::LoadCommands() {
	// Populate list with commands
	// (Keep in alphabetical order... it's MUCH easier)
	_commands.push_back( new oCmdCommands );
	_commands.push_back( new oCmdDescription );
	_commands.push_back( new oCmdExit );
	_commands.push_back( new  CmdGecho );
	_commands.push_back( new  CmdHelp );
	_commands.push_back( new oCmdLong );
	_commands.push_back( new oCmdKeywords );
	_commands.push_back( new  CmdReply );
	_commands.push_back( new  CmdSay );
	_commands.push_back( new oCmdShort );
	_commands.push_back( new  CmdTell );
	_commands.push_back( new oCmdView );
	return true;
}

Command* oCommandTable::FindCommand( Character* c, const string& command, bool shortcut ) {
	list< Command* >::iterator it;
	string command1;
	rtrim( command1, command );

	for ( it = _commands.begin(); it != _commands.end(); ++it ) {
		
		// If it's a shortcut, check against the commands shortcut
		if ( shortcut == true && !(*it)->_shortcut.empty() ) {
			if ( ( str_cmp( (*it)->_shortcut, command1 ) ) ) {
				if ( (*it)->_enabled == false ) {
					c->Send( "That command is disabled.\n\r" );
					return NULL;
				} else if ( (*it)->_enabled == false ) {
					c->Send( "That is an invalid command.\n\r" );
					return NULL;
				}
				return (*it);
			}
		}	
		if ( str_cmp( (*it)->_name, command1 ) || str_prefix( command1, (*it)->_name ) ) {
		   return (*it);
		}
	}
	return NULL;
}

bool oCommandTable::Execute( Character* c, const string& commandAndArgs ) {
	string commandss = commandAndArgs;
	string command1;
	string arguments;
	Command* command = 0;
	string buf;
	bool shortcut = false;
	list< Command* >::iterator it;

	if ( commandAndArgs.empty() || commandAndArgs[0] == '\n' || commandAndArgs[0] == '\r' )
		return false;

	// Check to see if there is a 'shortcut' used. Really checking if
	// it's a nonalphanumeric character.	
	for ( string::iterator cChar = commandss.begin(); cChar != commandss.end(); ++cChar ) {
		if ( !isalpha( (*cChar) ) && !isdigit( (*cChar) ) && cChar == commandss.begin() ) {
			command1 = (*cChar);
			shortcut = true;
		} else {
			arguments << (*cChar);
		}
	 }
	 // No shortcut
	 if ( shortcut == false ) {
		 arguments.erase();
		 split( commandAndArgs, command1, arguments );
		 rtrim( command1, command1 );
		 rtrim( arguments, arguments );
	 }

	if ( ( command = FindCommand( c, command1, shortcut ) ) != 0 ) {
		if ( command->_omniset ) {
			std::string omni;
			omni << c->getName() << " [oedit]: " << command->_name;
			if ( !arguments.empty() )
				omni << " \"" << arguments << "\"";
			World::Instance().Omninet( omni, STANDARD, c, true );
		}
		command->Execute( c, arguments );
		return true;
	}

	c->Send( "That is an invalid command.\n\r" );
	return false;
}

/////////////////////////////////////// redit command table //////////////////////////////////////

rCommandTable::rCommandTable() {	
	LoadCommands();	
}

bool rCommandTable::LoadCommands() {
	// Populate list with commands
	// (Keep in alphabetical order... it's MUCH easier)
	_commands.push_back( new rCmdCommands );
	_commands.push_back( new  CmdDown );
	_commands.push_back( new rCmdDescription );
	_commands.push_back( new rCmdDig );
	_commands.push_back( new  CmdEast );
	_commands.push_back( new rCmdExit );
	_commands.push_back( new  CmdGecho );
	_commands.push_back( new  CmdGoto );
	_commands.push_back( new  CmdHelp );
	_commands.push_back( new rCmdInfo );
	_commands.push_back( new  CmdLook );
	_commands.push_back( new rCmdLink );
	_commands.push_back( new rCmdMake );
	_commands.push_back( new  CmdNorth );
	_commands.push_back( new rCmdName );
	_commands.push_back( new rCmdRemove );
	_commands.push_back( new  CmdReply );
	_commands.push_back( new rCmdReset );
	_commands.push_back( new rCmdRlist );
	_commands.push_back( new  CmdSouth );
	_commands.push_back( new CmdSay );
	_commands.push_back( new rCmdSector );
	_commands.push_back( new  CmdTell );
	_commands.push_back( new  CmdUp );
	_commands.push_back( new rCmdUnlink );
	_commands.push_back( new  CmdWest );
	return true;
}

Command* rCommandTable::FindCommand( Character* c, const string& command, bool shortcut ) {
	list< Command* >::iterator it;
	string command1;
	rtrim( command1, command );

	for ( it = _commands.begin(); it != _commands.end(); ++it ) {
		
		// If it's a shortcut, check against the commands shortcut
		if ( shortcut == true && !(*it)->_shortcut.empty() ) {
			if ( ( str_cmp( (*it)->_shortcut, command1 ) ) ) {
				if ( (*it)->_enabled == false ) {
					c->Send( "That command is disabled.\n\r" );
					return NULL;
				} else if ( (*it)->_enabled == false ) {
					c->Send( "That is an invalid command.\n\r" );
					return NULL;
				}
				return (*it);
			}
		}	
		if ( str_cmp( (*it)->_name, command1 ) || str_prefix( command1, (*it)->_name ) ) {
		   return (*it);
		}
	}
	return NULL;
}

bool rCommandTable::Execute( Character* c, const string& commandAndArgs ) {
	string commandss = commandAndArgs;
	string command1;
	string arguments;
	Command* command = 0;
	string buf;
	bool shortcut = false;
	list< Command* >::iterator it;

	if ( commandAndArgs.empty() || commandAndArgs[0] == '\n' || commandAndArgs[0] == '\r' )
		return false;

	// Check to see if there is a 'shortcut' used. Really checking if
	// it's a nonalphanumeric character.	
	for ( string::iterator cChar = commandss.begin(); cChar != commandss.end(); ++cChar ) {
		if ( !isalpha( (*cChar) ) && !isdigit( (*cChar) ) && cChar == commandss.begin() ) {
			command1 = (*cChar);
			shortcut = true;
		} else {
			arguments << (*cChar);
		}
	 }
	 // No shortcut
	 if ( shortcut == false ) {
		 arguments.erase();
		 split( commandAndArgs, command1, arguments );
		 rtrim( command1, command1 );
		 rtrim( arguments, arguments );
	 }

	if ( ( command = FindCommand( c, command1, shortcut ) ) != 0 ) {
		if ( command->_omniset ) {
			std::string omni;
			omni << c->getName() << " [redit]: " << command->_name;
			if ( !arguments.empty() )
				omni << " \"" << arguments << "\"";
			World::Instance().Omninet( omni, STANDARD, c, true );
		}
		command->Execute( c, arguments );
		return true;
	}

	c->Send( "That is an invalid command.\n\r" );
	return false;
}

/////////////////////////////////////// pedit command table //////////////////////////////////////

pCommandTable::pCommandTable() {	
	LoadCommands();	
}

bool pCommandTable::LoadCommands() {
	// Populate list with commands
	// (Keep in alphabetical order... it's MUCH easier)
	_commands.push_back( new pCmdAge );
	_commands.push_back( new pCmdCommands );
	_commands.push_back( new pCmdExit );
	_commands.push_back( new pCmdEchoColor );
	_commands.push_back( new pCmdGender );
	_commands.push_back( new  CmdHelp );
	_commands.push_back( new pCmdLname );
	_commands.push_back( new pCmdName );
	return true;
}

Command* pCommandTable::FindCommand( Character* c, const string& command, bool shortcut ) {
	list< Command* >::iterator it;
	string command1;
	rtrim( command1, command );

	for ( it = _commands.begin(); it != _commands.end(); ++it ) {
		
		// If it's a shortcut, check against the commands shortcut
		if ( shortcut == true && !(*it)->_shortcut.empty() ) {
			if ( ( str_cmp( (*it)->_shortcut, command1 ) ) ) {
				if ( (*it)->_enabled == false ) {
					c->Send( "That command is disabled.\n\r" );
					return NULL;
				} else if ( (*it)->_enabled == false ) {
					c->Send( "That is an invalid command.\n\r" );
					return NULL;
				}
				return (*it);
			}
		}	
		if ( str_cmp( (*it)->_name, command1 ) || str_prefix( command1, (*it)->_name ) ) {
		   return (*it);
		}
	}
	return NULL;
}

bool pCommandTable::Execute( Character* c, const string& commandAndArgs ) {
	string commandss = commandAndArgs;
	string command1;
	string arguments;
	Command* command = 0;
	string buf;
	bool shortcut = false;
	list< Command* >::iterator it;

	if ( commandAndArgs.empty() || commandAndArgs[0] == '\n' || commandAndArgs[0] == '\r' )
		return false;

	// Check to see if there is a 'shortcut' used. Really checking if
	// it's a nonalphanumeric character.	
	for ( string::iterator cChar = commandss.begin(); cChar != commandss.end(); ++cChar ) {
		if ( !isalpha( (*cChar) ) && !isdigit( (*cChar) ) && cChar == commandss.begin() ) {
			command1 = (*cChar);
			shortcut = true;
		} else {
			arguments << (*cChar);
		}
	 }
	 // No shortcut
	 if ( shortcut == false ) {
		 arguments.erase();
		 split( commandAndArgs, command1, arguments );
		 rtrim( command1, command1 );
		 rtrim( arguments, arguments );
	 }

	if ( ( command = FindCommand( c, command1, shortcut ) ) != 0 ) {
		if ( command->_omniset ) {
			std::string omni;
			omni << c->getName() << " [aedit]: " << command->_name;
			if ( !arguments.empty() )
				omni << " \"" << arguments << "\"";
			World::Instance().Omninet( omni, STANDARD, c, true );
		}
		command->Execute( c, arguments );
		return true;
	}

	c->Send( "That is an invalid command.\n\r" );
	return false;
}

/////////////////////////////////////// vedit command table //////////////////////////////////////

vCommandTable::vCommandTable() {	
	LoadCommands();	
}

bool vCommandTable::LoadCommands() {
	// Populate list with commands
	// (Keep in alphabetical order... it's MUCH easier)
	_commands.push_back( new vCmdAdd );
	_commands.push_back( new vCmdExit );
	_commands.push_back( new vCmdHelp );
	_commands.push_back( new vCmdInsert );
	_commands.push_back( new vCmdRemove );
	_commands.push_back( new vCmdReplace );
	return true;
}

Command* vCommandTable::FindCommand( Character* c, const string& command, bool shortcut ) {
	list< Command* >::iterator it;
	string command1;
	rtrim( command1, command );

	for ( it = _commands.begin(); it != _commands.end(); ++it ) {
		
		// If it's a shortcut, check against the commands shortcut
		if ( shortcut == true && !(*it)->_shortcut.empty() ) {
			if ( ( str_cmp( (*it)->_shortcut, command1 ) ) ) {
				if ( (*it)->_enabled == false )
					return 0;
				else if ( (*it)->_enabled == false )
					return 0;
				return (*it);
			}
		}	
		if ( str_cmp( (*it)->_name, command1 ) || str_prefix( command1, (*it)->_name ) ) {
		   return (*it);
		}
	}
	return 0;
}

bool vCommandTable::Execute( Character* c, const string& commandAndArgs ) {
	string commandss = commandAndArgs;
	string command1;
	string arguments;
	Command* command = 0;
	string buf;
	bool shortcut = false;
	list< Command* >::iterator it;

	if ( commandAndArgs.empty() || commandAndArgs[0] == '\n' || commandAndArgs[0] == '\r' )
		return false;

	// Check to see if there is a 'shortcut' used. Really checking if
	// it's a nonalphanumeric character.	
	for ( string::iterator cChar = commandss.begin(); cChar != commandss.end(); ++cChar ) {
		if ( !isalpha( (*cChar) ) && !isdigit( (*cChar) ) && cChar == commandss.begin() ) {
			command1 = (*cChar);
			shortcut = true;
		} else {
			arguments << (*cChar);
		}
	 }
	 // No shortcut
	 if ( shortcut == false ) {
		 arguments.erase();
		 split( commandAndArgs, command1, arguments );
		 rtrim( command1, command1 );
		 rtrim( arguments, arguments );
	 }

	if ( ( command = FindCommand( c, command1, shortcut ) ) != NULL ) {
		command->Execute( c, arguments );
		return true;
	} else {
		
		return false;
	}
}

#endif // #ifndef __COMMANDTABLE_CPP_
